AWS CloudFormationでAmazon Lex ボット作成時、バージョンのみ手動作成するバージョン管理手法

AWS CloudFormationでAmazon Lex ボット作成時、バージョンのみ手動作成するバージョン管理手法

Clock Icon2024.08.01

はじめに

Amazon Lex ボットの開発において、AWS CloudFormationと手動操作を組み合わせたバージョン管理手法を紹介します。この方法では、ボットの基本構造をCloudFormationで管理しつつ、バージョン作成のみを手動で行うことで、柔軟性とリソース作成の効率性を両立させます。

この手法を採用することで、テンプレートのコード量を抑えながら、細やかなバージョン管理が可能になります。

Amazon Lexのバージョンとエイリアスについての詳細は、以下のリンクをご参照ください。

https://dev.classmethod.jp/articles/amazon-lex-versioning-and-draft-version/

前回の記事では、AWS CloudFormationを使用してAmazon Lexのバージョンを作成する際の挙動を確認し、以下のことが確認できました。

  • 新しいバージョンを追加しつつ、元のバージョンを残す場合は、テンプレートにリソースとしてボットバージョンを追加する必要がある
    • テンプレートのコード量がどんどん増えてしまうデメリットが存在する
  • 元のバージョンが不要な場合は、テンプレートのバージョンの論理名を変更するだけでよい
  • CloudFormationでバージョンを作成する場合、ボットの構築(Build)が自動的に行われる

そのなかで、新しいバージョンを追加しつつ、元のバージョンを残す場合は、テンプレートにリソースとしてボットバージョンを追加する必要があるため、バージョンを作成する度に、テンプレート内のコード量が肥大化する問題がありました。

そのため、今回は、新しいバージョンを追加しつつ、元のバージョンも残す案として、バージョンのみテンプレートからは作成しない方法を紹介します。

利用するCloudFormationテンプレート

今回は以下のLexボットを作成するテンプレートを利用します。
このボットは、Amazon Connectから呼び出され、特定の商材名を聞き取ります。音声をS3バケットに保存し、Lexでの文字起こし内容をログとしてCloudWatch Logsに保存します。

バージョンは作成しませんが、エイリアスは作成するテンプレートです。

AWSTemplateFormatVersion: 2010-09-09
Description: Amazon Lex Bot with Intent creation (Japanese)

Parameters:
  LexBotName:
    Type: String
    Default: cm-hirai-product-name
    Description: The name of the Lex bot
  SlotName:
    Type: String
    Default: name
    Description: The name of the slot
  CustomSlotTypeName:
    Type: String
    Default: productname
    Description: The name of the custom slot type
  AliasName:
    Type: String
    AllowedValues:
      - dev
      - prd
    Default: dev
    Description: The alias name for the Lex bot

Resources:
  MyLexBot:
    Type: AWS::Lex::Bot
    Properties:
      Name: !Ref LexBotName
      Description: !Ref LexBotName
      DataPrivacy: 
        ChildDirected: false
      IdleSessionTTLInSeconds: 300
      RoleArn: !GetAtt LexBotRole.Arn
      BotLocales:
        - LocaleId: ja_JP  
          NluConfidenceThreshold: 0.40
          VoiceSettings:
            VoiceId: Kazuha
          Intents:
            - Name: FallbackIntent
              ParentIntentSignature: AMAZON.FallbackIntent
            - Name: ProductName
              SampleUtterances:
                - Utterance: '{name}'
                - Utterance: 商材名は、{name}です。
                - Utterance: '{name}です。'
                - Utterance: 聞きたいのは、{name}についてです。
              Slots:
                - Name: !Ref SlotName
                  SlotTypeName: !Ref CustomSlotTypeName
                  ValueElicitationSetting:
                    SlotConstraint: Required
                    PromptSpecification:
                      MaxRetries: 3
                      MessageGroupsList:
                        - Message: 
                            PlainTextMessage: 
                              Value: 商材名をお伝え下さい。
              IntentConfirmationSetting: 
                PromptSpecification:
                  MaxRetries: 3
                  MessageGroupsList:
                    - Message:
                        PlainTextMessage:
                          Value: 商材名は、{name}、ですね。よろしければ、はい、と、異なる場合、いいえ、とお伝え下さい。
                ## 確認プロンプトに NOと伝えた場合のボットのプロンプト
                # DeclinationResponse:
                #   MessageGroupsList:
                #     - Message:
                #         PlainTextMessage:
                #           Value: 正しく商材名を聞き取れず、申し訳ございません。
              ## 応答を閉じる
              # IntentClosingSetting:
              #   ClosingResponse:
              #     MessageGroupsList:
              #       - Message:
              #           PlainTextMessage:
              #             Value: 担当者にお繋ぎします
              SlotPriorities:
                - Priority: 1
                  SlotName: !Ref SlotName
          SlotTypes:
            - Name: !Ref CustomSlotTypeName
              ValueSelectionSetting:
                ResolutionStrategy: ORIGINAL_VALUE
              SlotTypeValues:
                - SampleValue: 
                    Value: Wifi
                - SampleValue: 
                    Value: ウォーターサーバー
                - SampleValue: 
                    Value: スマートホームデバイス
                - SampleValue: 
                    Value: 電動自転車
      TestBotAliasSettings:
        BotAliasLocaleSettings:
          - LocaleId: ja_JP
            BotAliasLocaleSetting:
              Enabled: true
              ## Lambdaを利用する場合
              # CodeHookSpecification:
              #   LambdaCodeHook:
              #     LambdaArn: !GetAtt LambdaFunction.Arn
        ConversationLogSettings:
          TextLogSettings:
            - Enabled: true
              Destination: 
                CloudWatch: 
                  CloudWatchLogGroupArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}"
                  LogPrefix: TestBotAlias/
          AudioLogSettings:
            - Enabled: true
              Destination:
                S3Bucket:
                  S3BucketArn: !GetAtt S3Bucket.Arn
                  LogPrefix: TestBotAlias/
  # バージョンを利用する場合
  # BotVersion1:
  #   Type: AWS::Lex::BotVersion
  #   Properties:
  #     BotId: !Ref MyLexBot
  #     BotVersionLocaleSpecification:
  #       - LocaleId: ja_JP
  #         BotVersionLocaleDetails:
  #           SourceBotVersion: DRAFT
  MyLexBotAlias:
    Type: AWS::Lex::BotAlias
    Properties:
      BotAliasName: dev
      BotId: !Ref MyLexBot
      # バージョンを利用する場合
      # BotVersion: !GetAtt BotVersion1.BotVersion
      ConversationLogSettings:
        TextLogSettings:
          - Enabled: true
            Destination: 
              CloudWatch: 
                CloudWatchLogGroupArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}"
                LogPrefix: dev/
        AudioLogSettings:
          - Enabled: true
            Destination:
              S3Bucket:
                S3BucketArn: !GetAtt S3Bucket.Arn
                LogPrefix: dev/
  LexBotRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lexv2.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub ${LexBotName}-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - polly:SynthesizeSpeech
                Resource: '*'
              - Effect: Allow
                Action: 
                  - s3:PutObject
                Resource: 
                  - !Sub "arn:aws:s3:::${S3Bucket}/*"
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: 
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}:*"
  CloudWatchLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lex/${LexBotName}"
      RetentionInDays: 365
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref LexBotName

パラメータは、以下の内容でスタックを作成します。
cm-hirai-screenshot 2024-07-18 9.39.37

スタックを作成すると、バージョンはテンプレートに記載していませんが、ドラフトバージョンは自動作成されます。
cm-hirai-screenshot 2024-07-18 11.33.11
バージョンは作成していないため、エイリアスdevは作成されますが、バージョンには関連付けられてはいません。
cm-hirai-screenshot 2024-07-18 11.33.16

このテンプレートからバージョンのみを手動で作成します。

バージョンのみ手動で作成

バージョンのみを手動で作成する場合、AWS CLIのコマンドをスタックの出力に記載し、その出力内のコマンドを1行ずつ実行することで、バージョンの作成とエイリアスとの関連付けできるようにします。

最初に紹介したテンプレートに、以下のようにOutputsセクションを追加します。

CloudFormationテンプレート
AWSTemplateFormatVersion: 2010-09-09
Description: Amazon Lex Bot with Intent creation (Japanese)

Parameters:
  LexBotName:
    Type: String
    Default: cm-hirai-product-name
    Description: The name of the Lex bot
  SlotName:
    Type: String
    Default: name
    Description: The name of the slot
  CustomSlotTypeName:
    Type: String
    Default: productname
    Description: The name of the custom slot type
  AliasName:
    Type: String
    AllowedValues:
      - dev
      - prd
    Default: dev
    Description: The alias name for the Lex bot

Resources:
  MyLexBot:
    Type: AWS::Lex::Bot
    Properties:
      Name: !Ref LexBotName
      Description: !Ref LexBotName
      DataPrivacy: 
        ChildDirected: false
      IdleSessionTTLInSeconds: 300
      RoleArn: !GetAtt LexBotRole.Arn
      BotLocales:
        - LocaleId: ja_JP  
          NluConfidenceThreshold: 0.40
          VoiceSettings:
            VoiceId: Kazuha
          Intents:
            - Name: FallbackIntent
              ParentIntentSignature: AMAZON.FallbackIntent
            - Name: ProductName
              SampleUtterances:
                - Utterance: '{name}'
                - Utterance: 商材名は、{name}です。
                - Utterance: '{name}です。'
                - Utterance: 聞きたいのは、{name}についてです。
              Slots:
                - Name: !Ref SlotName
                  SlotTypeName: !Ref CustomSlotTypeName
                  ValueElicitationSetting:
                    SlotConstraint: Required
                    PromptSpecification:
                      MaxRetries: 3
                      MessageGroupsList:
                        - Message: 
                            PlainTextMessage: 
                              Value: 商材名をお伝え下さい。
              IntentConfirmationSetting: 
                PromptSpecification:
                  MaxRetries: 3
                  MessageGroupsList:
                    - Message:
                        PlainTextMessage:
                          Value: 商材名は、{name}、ですね。よろしければ、はい、と、異なる場合、いいえ、とお伝え下さい。
                ## 確認プロンプトに NOと伝えた場合のボットのプロンプト
                # DeclinationResponse:
                #   MessageGroupsList:
                #     - Message:
                #         PlainTextMessage:
                #           Value: 正しく商材名を聞き取れず、申し訳ございません。
              ## 応答を閉じる
              # IntentClosingSetting:
              #   ClosingResponse:
              #     MessageGroupsList:
              #       - Message:
              #           PlainTextMessage:
              #             Value: 担当者にお繋ぎします
              SlotPriorities:
                - Priority: 1
                  SlotName: !Ref SlotName
          SlotTypes:
            - Name: !Ref CustomSlotTypeName
              ValueSelectionSetting:
                ResolutionStrategy: ORIGINAL_VALUE
              SlotTypeValues:
                - SampleValue: 
                    Value: Wifi
                - SampleValue: 
                    Value: ウォーターサーバー
                - SampleValue: 
                    Value: スマートホームデバイス
                - SampleValue: 
                    Value: 電動自転車
      TestBotAliasSettings:
        BotAliasLocaleSettings:
          - LocaleId: ja_JP
            BotAliasLocaleSetting:
              Enabled: true
              ## Lambdaを利用する場合
              # CodeHookSpecification:
              #   LambdaCodeHook:
              #     LambdaArn: !GetAtt LambdaFunction.Arn
        ConversationLogSettings:
          TextLogSettings:
            - Enabled: true
              Destination: 
                CloudWatch: 
                  CloudWatchLogGroupArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}"
                  LogPrefix: TestBotAlias/
          AudioLogSettings:
            - Enabled: true
              Destination:
                S3Bucket:
                  S3BucketArn: !GetAtt S3Bucket.Arn
                  LogPrefix: TestBotAlias/
  # バージョンを利用する場合
  # BotVersion1:
  #   Type: AWS::Lex::BotVersion
  #   Properties:
  #     BotId: !Ref MyLexBot
  #     BotVersionLocaleSpecification:
  #       - LocaleId: ja_JP
  #         BotVersionLocaleDetails:
  #           SourceBotVersion: DRAFT
  MyLexBotAlias:
    Type: AWS::Lex::BotAlias
    Properties:
      BotAliasName: dev
      BotId: !Ref MyLexBot
      # バージョンを利用する場合
      # BotVersion: !GetAtt BotVersion1.BotVersion
      ConversationLogSettings:
        TextLogSettings:
          - Enabled: true
            Destination: 
              CloudWatch: 
                CloudWatchLogGroupArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}"
                LogPrefix: dev/
        AudioLogSettings:
          - Enabled: true
            Destination:
              S3Bucket:
                S3BucketArn: !GetAtt S3Bucket.Arn
                LogPrefix: dev/
  LexBotRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lexv2.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub ${LexBotName}-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - polly:SynthesizeSpeech
                Resource: '*'
              - Effect: Allow
                Action: 
                  - s3:PutObject
                Resource: 
                  - !Sub "arn:aws:s3:::${S3Bucket}/*"
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: 
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}:*"
  CloudWatchLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lex/${LexBotName}"
      RetentionInDays: 365
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref LexBotName

Outputs:
  01BuildBot:
    Value: !Sub |+
        aws lexv2-models build-bot-locale 
            --bot-id "${MyLexBot}" 
            --bot-version "DRAFT" 
            --locale-id "ja_JP"
  02CheckBuildStatus:
    Value: !Sub |+
        aws lexv2-models describe-bot-locale 
            --bot-id "${MyLexBot}" 
            --bot-version "DRAFT" 
            --locale-id "ja_JP" 
            --query 'botLocaleStatus'
  03CreateBotVersion:
    Value: !Sub |+
        BOT_VERSION=$(aws lexv2-models create-bot-version 
          --bot-id "${MyLexBot}" 
          --bot-version-locale-specification '{
                "ja_JP": {
                    "sourceBotVersion": "DRAFT"
                }
            }' 
          --description "Your bot version description" 
          --output json | jq -r '.botVersion')
  03EchoBotVersion:
    Value: |+
        echo "The bot version you created: $BOT_VERSION"
  04AssociateAlias:
    Value: !Sub |+
        aws lexv2-models update-bot-alias 
            --bot-alias-id "${MyLexBotAlias.BotAliasId}" 
            --bot-id "${MyLexBot}" 
            --bot-alias-name "${AliasName}" 
            --bot-version "$BOT_VERSION" 
            --conversation-log-settings '{
                "textLogSettings": [
                    {
                        "enabled": true,
                        "destination": {
                            "cloudWatch": {
                                "cloudWatchLogGroupArn": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}",
                                "logPrefix": "${AliasName}/"
                            }
                        }
                    }
                ],
                "audioLogSettings": [
                    {
                        "enabled": true,
                        "destination": {
                            "s3Bucket": {
                                "s3BucketArn": "${S3Bucket.Arn}",
                                "logPrefix": "${AliasName}/"
                            }
                        }
                    }
                ]
            }'

追加した内容は以下の通りです。

Outputs:
  01BuildBot:
    Value: !Sub |+
        aws lexv2-models build-bot-locale 
            --bot-id "${MyLexBot}" 
            --bot-version "DRAFT" 
            --locale-id "ja_JP"
  02CheckBuildStatus:
    Value: !Sub |+
        aws lexv2-models describe-bot-locale 
            --bot-id "${MyLexBot}" 
            --bot-version "DRAFT" 
            --locale-id "ja_JP" 
            --query 'botLocaleStatus'
  03CreateBotVersion:
    Value: !Sub |+
        BOT_VERSION=$(aws lexv2-models create-bot-version 
          --bot-id "${MyLexBot}" 
          --bot-version-locale-specification '{
                "ja_JP": {
                    "sourceBotVersion": "DRAFT"
                }
            }' 
          --description "Your bot version description" 
          --output json | jq -r '.botVersion')
  03EchoBotVersion:
    Value: |+
        echo "The bot version you created: $BOT_VERSION"
  04AssociateAlias:
    Value: !Sub |+
        aws lexv2-models update-bot-alias 
            --bot-alias-id "${MyLexBotAlias.BotAliasId}" 
            --bot-id "${MyLexBot}" 
            --bot-alias-name "${AliasName}" 
            --bot-version "$BOT_VERSION" 
            --conversation-log-settings '{
                "textLogSettings": [
                    {
                        "enabled": true,
                        "destination": {
                            "cloudWatch": {
                                "cloudWatchLogGroupArn": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${CloudWatchLogGroup}",
                                "logPrefix": "${AliasName}/"
                            }
                        }
                    }
                ],
                "audioLogSettings": [
                    {
                        "enabled": true,
                        "destination": {
                            "s3Bucket": {
                                "s3BucketArn": "${S3Bucket.Arn}",
                                "logPrefix": "${AliasName}/"
                            }
                        }
                    }
                ]
            }'

新しく上記のテンプレートでスタックを作成します。

スタックの出力は以下の通りです。

cm-hirai-screenshot 2024-07-22 15.41.49

スタックの出力(Output)をそのままコピペして実行するだけで作成したバージョンをエイリアスと関連付けまで対応できます。

$ aws lexv2-models build-bot-locale --bot-id "${MyLexBot}" --bot-version "DRAFT" --locale-id "ja_JP"
$ aws lexv2-models describe-bot-locale --bot-id "${MyLexBot}" --bot-version "DRAFT" --locale-id "ja_JP" --query 'botLocaleStatus'
$ BOT_VERSION=$(aws lexv2-models create-bot-version --bot-id "${MyLexBot}" --bot-version-locale-specification '{ "ja_JP": { "sourceBotVersion": "DRAFT" } }' --description "Your bot version description" --output json | jq -r '.botVersion')
$ echo "The bot version you created: $BOT_VERSION"
$ aws lexv2-models update-bot-alias --bot-alias-id "${AliasName}"  --bot-id "${MyLexBot}" --bot-alias-name "${AliasName}" --bot-version "$BOT_VERSION" --conversation-log-settings '{ "textLogSettings": [ { "enabled": true, "destination": { "cloudWatch": { "cloudWatchLogGroupArn": "arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:log-group:${CloudWatchLogGroup}", "logPrefix": "${AliasName}/" } } } ], "audioLogSettings": [ { "enabled": true, "destination": { "s3Bucket": { "s3BucketArn": "${S3Bucket.Arn}", "logPrefix": "${AliasName}/" } } } ] }'

${〇〇}は変数であり、スタックの出力(Output)には実際の値が入ります。

5つのコマンドの流れとしては以下の通りです。

  1. ボットをビルドする
  2. ボットの構築ステータスを確認する
  3. バージョンを作成する
  4. ボットのバージョンを確認する
  5. 作成したバージョンをエイリアスと関連付ける

各コマンドを解説します。

ボットをビルドする

バージョンを作成する前に、ボットをビルドする必要があります。

手動でバージョンを作成する場合、以下のような状況では、ボットをビルドしてからバージョンを作成する必要があります

  • ボット作成直後にバージョンを作成する場合
  • ボットを作成しビルド後、設定変更をしたため、その変更内容を反映したバージョンを作成する場合

ドラフトバージョンをビルドせずにバージョンを作成すると、そのバージョンには設定変更内容が反映されません。また、ボット作成直後にビルドしない場合、ボット自体利用することができません。

余談ですが、CloudFormationでバージョンを作成する場合、スタックの更新中に自動的にビルドが行われます。

したがって、スタック作成後にドラフトバージョンをコマンドでビルドします。

$ aws lexv2-models build-bot-locale --bot-id "WNMQERKB1Z" --bot-version "DRAFT" --locale-id "ja_JP"

ビルドには時間がかかります。今回は、1分弱ほどかかりました。2つ目のコマンドでビルドステータスが確認できます。

$ aws lexv2-models describe-bot-locale --bot-id "WNMQERKB1Z" --bot-version "DRAFT" --locale-id "ja_JP" --query 'botLocaleStatus'
"Building"

$ aws lexv2-models describe-bot-locale --bot-id "WNMQERKB1Z" --bot-version "DRAFT" --locale-id "ja_JP" --query 'botLocaleStatus'
"ReadyExpressTesting"

$ aws lexv2-models describe-bot-locale --bot-id "WNMQERKB1Z" --bot-version "DRAFT" --locale-id "ja_JP" --query 'botLocaleStatus'
"Built"

今回は、ビルドが完了するまでに以下のステータスが確認できました。

  • Building: ビルド中であり、テストできない
  • ReadyExpressTesting:インテントとスロットタイプに定義された発話を使用してボットをテストできます。
  • Built:ボットは使用できる状態であり、任意の発話を使用してテストできます。

他にも、ビルドに失敗した場合のFailedなどのステータスが用意されています。詳細は以下のドキュメントをご参照ください。

https://docs.aws.amazon.com/ja_jp/lexv2/latest/APIReference/API_BuildBotLocale.html

https://docs.aws.amazon.com/ja_jp/lexv2/latest/APIReference/API_DescribeBotLocale.html

バージョンを作成

以下のコマンドでバージョンを作成します。

$ BOT_VERSION=$(aws lexv2-models create-bot-version --bot-id "WNMQERKB1Z" --bot-version-locale-specification '{ "ja_JP": { "sourceBotVersion": "DRAFT" } }' --description "Your bot version description" --output json | jq -r '.botVersion')

バージョン1が作成されました。

以下のコマンドで作成されたバージョン数が確認できます。

$ echo "The bot version you created: $BOT_VERSION"
The bot version you created: 1

変数のBOT_VERSIONは、次のバージョンをエイリアスに関連付ける際に利用します。

https://docs.aws.amazon.com/ja_jp/lexv2/latest/APIReference/API_CreateBotVersion.html

バージョンをエイリアスに関連付け

最後に、作成したバージョンをエイリアスに関連付けます。

CloudFormationテンプレートで作成したエイリアスdevに、バージョン1を関連付けます。スタックの出力(Output)に記載されているコマンドをそのまま実行するだけで実現できます。

$ aws lexv2-models update-bot-alias --bot-alias-id "LPMCY0CEEZ" --bot-id "WNMQERKB1Z" --bot-alias-name "dev" --bot-version "$BOT_VERSION" --conversation-log-settings '{ "textLogSettings": [ { "enabled": true, "destination": { "cloudWatch": { "cloudWatchLogGroupArn": "arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:log-group:/aws/lex/cm-hirai-product-name", "logPrefix": "dev/" } } } ], "audioLogSettings": [ { "enabled": true, "destination": { "s3Bucket": { "s3BucketArn": "arn:aws:s3:::cm-hirai-product-name", "logPrefix": "dev/" } } } ] }'
{
    "botAliasId": "LPMCY0CEEZ",
    "botAliasName": "dev",
    "botVersion": "1",
    "conversationLogSettings": {
        "textLogSettings": [
            {
                "enabled": true,
                "destination": {
                    "cloudWatch": {
                        "cloudWatchLogGroupArn": "arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:log-group:/aws/lex/cm-hirai-product-name",
                        "logPrefix": "dev/"
                    }
                }
            }
        ],
        "audioLogSettings": [
            {
                "enabled": true,
                "destination": {
                    "s3Bucket": {
                        "s3BucketArn": "arn:aws:s3:::cm-hirai-product-name",
                        "logPrefix": "dev/"
                    }
                }
            }
        ]
    },
    "botAliasStatus": "Available",
    "botId": "WNMQERKB1Z",
    "creationDateTime": "2024-07-22T04:45:07.382000+00:00",
    "lastUpdatedDateTime": "2024-07-22T05:30:14.347000+00:00"
}

https://docs.aws.amazon.com/ja_jp/lexv2/latest/APIReference/API_UpdateBotAlias.html

作成したバージョンのボットのログ出力設定もしてます。ログ出力の設定を記載しない場合、エイリアスの会話ログは無効化されます。

エイリアスがバージョン1に関連付けされました。

cm-hirai-screenshot 2024-07-22 15.17.24

Lexの設定を変更するためにCloudFormationテンプレートを修正してスタックを更新した場合、テンプレート内ではエイリアスdevとバージョン1の関連付けを行っていませんが、スタック更新後もエイリアスdevはバージョン1に関連付けられたままとなります。
また、バージョン1も削除はされません。

cm-hirai-screenshot 2024-07-18 15.21.16
CloudFormationテンプレートを変更し、スタック更新後もバージョン1は削除されない
cm-hirai-screenshot 2024-07-18 15.21.30
CloudFormationテンプレートを変更し、スタック更新後もエイリアスdevとバージョン1は関連付けされたまま

スタック更新後、スタックの出力コマンドを実行すると、バージョン2が作成され、エイリアスdevと関連付けられます。

最後に

AWS CloudFormationを使用してAmazon Lex ボットを作成する際、バージョン作成のみを手動で行う選択肢があることを紹介しました。

この方法を利用することで、テンプレートのコード量を抑えつつ、柔軟にバージョン管理を行うことができます。

参考になれば幸いです。

参考

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/AWS_Lex.html

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.